import { registerApplication, start } from 'single-spa'
import axios from 'axios'
import eventRoot from './eventRoot'

// 远程加载子应用
function createScript(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = url
    script.onload = resolve
    script.onerror = reject
    const firstScript = document.getElementsByTagName('script')[0]
    firstScript.parentNode.insertBefore(script, firstScript)
  })
}

/*
* getManifest：远程加载manifest.json 文件，解析需要加载的js
* */
const getManifest = (url, bundle) => new Promise((resolve) => {
  axios.get(url).then(async res => {
    const { data } = res
    const { entrypoints, publicPath } = data
    const assets = entrypoints[bundle].assets
    for (let i = 0; i < assets.length; i++) {
      await createScript(publicPath + assets[i]).then(() => {
        if (i === assets.length - 1) {
          resolve()
        }
      })
    }
  })
})

// 子应用列表
const apps = [
  {
    // 子应用名称
    name: 'singleChild1',
    // 子应用加载函数，是一个promise
    app: async () => {
      let childModule = null
      await getManifest(`${process.env.VUE_APP_CHILD_ONE}/manifest.json?v=${new Date().getTime()}`, 'app').then(() => {
        childModule = window.singleChild1
      })
      return childModule
    },
    // 当路由满足条件时（返回true），激活（挂载）子应用
    activeWhen: location => {
      return location.pathname.startsWith('/singleChild1')
    },
    // 传递给子应用的对象
    customProps: { baseUrl: '/singleChild1', eventRoot }
  },
  {
    // 子应用名称
    name: 'singleChild2',
    // 子应用加载函数，是一个promise
    app: async () => {
      let childModule = null
      await getManifest(`${process.env.VUE_APP_CHILD_TWO}/manifest.json?v=${new Date().getTime()}`, 'app').then(() => {
        childModule = window.singleChild2
      })
      return childModule
    },
    // 当路由满足条件时（返回true），激活（挂载）子应用
    activeWhen: location => {
      return location.pathname.startsWith('/singleChild2')
    },
    // 传递给子应用的对象
    customProps: { baseUrl: '/singleChild2', eventRoot }
  }
]

apps.forEach(item => registerApplication(item))

start()
